<template>
  <div class="user-header">
    <div class="buttonTop">
      <el-button type="primary" @click="handleAdd">+新增</el-button>
      <el-button type="danger" @click="handleDelList" style="padding: 5px"
        >批量删除</el-button
      >
    </div>
    <el-form :inline="true" :model="menuFormInline" class="ef_1">
      <el-form-item>
        <el-input
          v-model="menuFormInline.keywords"
          placeholder="请输入菜单名检索"
          clearable
          prefix-icon="Search"
          class="ei_1"
          style="width: 190px"
        />
      </el-form-item>
      <el-form-item>
        <el-select
          v-model="menuFormInline.enable"
          prefix-icon="Search"
          clearable
          placeholder="请选择菜单状态"
          class="ei_1"
          style="width: 190px"
        >
          <el-option label="正常" value="1" />
          <el-option label="禁用" value="0" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handleSearch">搜索</el-button>
      </el-form-item>
    </el-form>
  </div>
  <!-- 表格数据 -->
  <div class="table">
    <el-table
      :data="menuTableData"
      style="width: 100%; height: 494px"
      ref="menuTableRef"
      border
      row-key="id"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" align="center" width="40" />
      <!-- <el-table-column
        type="index"
        label="菜单编号"
        align="center"
        width="100"
      ></el-table-column> -->
      <el-table-column
        prop="label"
        label="菜单名称"
        width="140"
        :show-overflow-tooltip="true"
      ></el-table-column>
      <el-table-column prop="icon" label="图标" align="center" width="80">
        <template #default="scope">
          <svg-icon
            :name="scope.row.icon"
            class="table-icon"
            :color="red"
          ></svg-icon>
          <!-- <component class="icons" :is="scope.row.icon"></component> -->
        </template>
      </el-table-column>
      <el-table-column prop="menuType" label="类型" align="center" width="80">
        <template #default="scope">
          <el-tag v-if="scope.row.menuType == 'C'">菜单</el-tag>
          <el-tag type="success" v-else-if="scope.row.menuType == 'M'"
            >目录</el-tag
          >
        </template>
      </el-table-column>
      <el-table-column
        prop="menuSort"
        label="显示排序"
        align="center"
        width="110"
      ></el-table-column>
      <el-table-column
        v-for="item in menuTableLabel"
        align="center"
        :key="item.prop"
        :prop="item.prop"
        :label="item.label"
        :show-overflow-tooltip="true"
        :width="item.width ? item.width : 125"
      />
      <el-table-column label="状态" align="center" prop="enable" width="80">
        <template #default="scope">
          <el-tag v-if="scope.row.enable == 1">正常</el-tag>
          <el-tag type="error" v-else-if="scope.row.enable == 0">禁用</el-tag>
        </template>
      </el-table-column>
      <el-table-column
        label="启用缓存"
        align="center"
        prop="keepAlive"
        width="110"
      >
        <template #default="{ row }">
          <el-switch
            v-show="row.menuType !== 'M'"
            v-model="row.keepAlive"
            inline-prompt
            inactive-color="#f56c6c"
            active-text="是"
            inactive-text="否"
            @change="changeMenuStatu(row)"
          />
        </template>
      </el-table-column>
      <el-table-column fixed="right" align="center" label="操作" width="150">
        <!--Vue组件中定义一个插槽，row为当前行的数据，从父组件中拿到的，可以打印{{row}}查看 -->
        <!--如果#default="scope" scope为作用域对象，你可以拿到这个vue模版中的所有的对象和方法 -->
        <template #default="{ row }">
          <!-- {{ scope.row }} -->
          <el-button link type="primary" icon="Edit" @click="handleEdit(row)"
            >编辑</el-button
          >
          <el-button link type="danger" icon="Delete" @click="handleRemove(row)"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>
  </div>
  <!--新增和编辑用户 dialogVisible：隐藏显示对话框视图 -->
  <el-dialog
    v-model="dialogVisible"
    :title="getAction.action === 'add' ? '新增用户' : '编辑用户'"
    width="40%"
    append-to-body
    draggable
  >
    <el-form
      ref="formMenuRef"
      :model="formMenu"
      :rules="rules"
      label-width="100px"
    >
      <el-row :gutter="10">
        <el-col :lg="24">
          <el-form-item label="上级菜单">
            <el-tree-select
              class="treeSelect"
              v-model="formMenu.parentId"
              :data="menuOptions"
              :props="{
                value: 'id',
                label: 'label',
                children: 'children',
              }"
              value-key="id"
              node-key="id"
              :show-count="true"
              placeholder="选择上级菜单"
              check-strictly
            />
          </el-form-item>
        </el-col>
        <el-col :lg="24">
          <el-form-item label="菜单类型" prop="menuType">
            <el-radio-group size="mini" v-model="formMenu.menuType">
              <el-radio-button label="M">目录</el-radio-button>
              <el-radio-button label="C">菜单</el-radio-button>
              <el-radio-button label="F">按钮</el-radio-button>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :lg="12">
          <el-form-item label="菜单名称" prop="label">
            <el-input v-model="formMenu.label" placeholder="请输入菜单名称" />
          </el-form-item>
        </el-col>
        <el-col :lg="12">
          <el-form-item label="显示排序" prop="menuSort">
            <el-input-number
              v-model="formMenu.menuSort"
              controls-position="right"
              :min="0"
              :value="999"
            />
          </el-form-item>
        </el-col>
        <el-col :lg="24" v-if="formMenu.menuType != 'F'">
          <el-form-item label="菜单图标" prop="icon">
            <el-popover placement="bottom-start" :width="540" trigger="click">
              <template #reference>
                <el-input
                  v-model="formMenu.icon"
                  placeholder="点击选择图标"
                  readonly
                  clearable
                >
                  <template #prefix>
                    <svg-icon v-if="formMenu.icon" :name="formMenu.icon" />
                    <el-icon v-else>
                      <search />
                    </el-icon>
                  </template>
                  <template #suffix>
                    <el-icon @click="selectedSvgIcon('')"><Delete /></el-icon>
                  </template>
                </el-input>
              </template>
              <IconSelect
                ref="iconSelectRef"
                @selectedSvgIcon="selectedSvgIcon"
              />
            </el-popover>
            <!-- <el-input v-model="formMenu.icon"></el-input> -->
            <!-- <el-link type="danger" @click="form.icon = ''">清空</el-link> -->
          </el-form-item>
        </el-col>
        <el-col :lg="12">
          <el-form-item v-if="formMenu.menuType != 'F'" label="菜单状态">
            <template #label>
              <span>
                <el-tooltip
                  content="选择停用,菜单将不会出现在侧边栏"
                  placement="top"
                >
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                菜单状态
              </span>
            </template>
            <el-select v-model="formMenu.enable">
              <el-option value="1" label="正常" />
              <el-option value="0" label="禁用" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :lg="12">
          <el-form-item v-if="formMenu.menuType != 'F'" prop="path">
            <template #label>
              <span>
                <el-tooltip
                  content="访问的路由地址，如：`/user`"
                  placement="top"
                >
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                路由地址
              </span>
            </template>
            <el-input v-model="formMenu.path" placeholder="请输入路由地址" />
          </el-form-item>
        </el-col>

        <el-col :lg="12" v-if="formMenu.menuType == 'C'">
          <el-form-item label="组件路径" prop="url">
            <template #label>
              <span>
                <el-tooltip
                  content="访问的组件路径，如：`system/user/User`，默认在`views`目录下"
                  placement="top"
                >
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                组件路径
              </span>
            </template>
            <el-input v-model="formMenu.url" placeholder="请输入组件路径" />
          </el-form-item>
        </el-col>

        <el-col :lg="12">
          <el-form-item v-if="formMenu.menuType != 'M'" label="权限标识">
            <template #label>
              <span slot="label">
                <el-tooltip
                  content="控制器中定义的权限字符，如：'system:user:delete'"
                  placement="top"
                >
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                权限标识
              </span>
            </template>
            <el-input
              v-model="formMenu.perms"
              placeholder="规范([分类]:[页面]:[动作])"
              maxlength="50"
            />
          </el-form-item>
        </el-col>

        <el-col :lg="12">
          <el-form-item v-if="formMenu.menuType == 'C'" label="是否缓存">
            <template #label>
              <span>
                <el-tooltip
                  content="选择是页面会被`keep-alive`缓存"
                  placement="top"
                >
                  <el-icon><question-filled /></el-icon>
                </el-tooltip>
                是否缓存
              </span>
            </template>
            <el-radio-group v-model="formMenu.keepAlive">
              <el-radio label="1">缓存</el-radio>
              <el-radio label="0">不缓存</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="handleCancel()">取 消</el-button>
      <el-button type="primary" @click="onSubmit()">确 定</el-button>
    </div>
  </el-dialog>
</template>
<script setup>
import {
  computed,
  defineComponent,
  getCurrentInstance,
  nextTick,
  onMounted,
  reactive,
  ref,
} from "vue";
import { ElMessageBox, ElMessage, ElDrawer } from "element-plus";
import IconSelect from "../../../components/svgIconSelect/index.vue";
const { proxy } = getCurrentInstance();
//  查询用户、分页、搜索用户实体
const config = reactive({
  menuName: "",
  enable: "",
});
// 复用模态框,新增和编辑
const getAction = reactive({
  action: "add",
});
// 双向绑定，为了关键词搜索
const menuFormInline = reactive({
  keywords: "",
  enable: "",
});
// 添加用户的form数据接收绑定
const formMenu = reactive({
  id: "",
  parentId: "",
  menuType: "",
  label: "",
  path: "",
  icon: "",
  url: "",
  menuSort: "",
  enable: "",
  keepAlive: "",
});
const rules = reactive({
  label: [{ required: true, message: "请输入菜单名称", trigger: "blur" }],
  icon: [{ required: true, message: "请选择图标", trigger: "blur" }],
  path: [{ required: true, message: "请输入路由地址", trigger: "blur" }],
  url: [{ required: true, message: "请输入组件路径", trigger: "blur" }],
  menuSort: [{ required: true, message: "请输入菜单排序", trigger: "blur" }],
});
// 表格列配置
const menuTableLabel = reactive([
  { label: "权限标识", prop: "perms" },
  { label: "路由地址", prop: "path" },
  { label: "组件路径", prop: "url", width: "200" },
]);
// 表格数据
const menuTableData = ref();

onMounted(() => {
  getMenuData(config);
});
// 获取菜单数据
const getMenuData = async (config) => {
  // 调用接口
  let res = await proxy.$api.menu.getMenuData(config);
  if (res) {
    menuTableData.value = res.data.map((item) => {
      return changeAliveValue(item);
    });
    console.log(
      "%c [ menuTableData.value ]-357",
      "font-size:13px; background:pink; color:#bf2c9f;",
      menuTableData.value
    );
  }
};
// 改变页面keepAlive的值，方便页面展示
// 递归改变所有数据的keepAlive属性
const changeAliveValue = (item) => {
  item.keepAlive = item.keepAlive === 1 ? true : false;

  if (item.children) {
    item.children = item.children.map((child) => {
      return changeAliveValue(child);
    });
  }
  return item;
};
//改变用户状态（是否禁用）
const changeMenuStatu = (row) => {
  let status = row.keepAlive === true ? "缓存" : "不缓存";
  ElMessageBox.confirm(
    `确定要 "${status}"   "${row.label}" 页面吗?`,
    "系统提示",
    {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    }
  )
    .then(async () => {
      const id = row.id;
      const keepAlive = row.keepAlive == true ? 1 : 0;
      let res = await proxy.$api.menu.changeMenuStatus({ id, keepAlive });
      if (res) {
        ElMessage({
          type: "success",
          message: res.data,
        });
        getMenuData(config);
      }
    })
    .catch(() => {
      row.keepAlive = row.keepAlive === true ? false : true;
    });
};
// 关键词搜索
const handleSearch = () => {
  config.menuName = menuFormInline.keywords;
  config.enable = menuFormInline.enable;
  getMenuData(config);
};

const dialogVisible = ref();
// 下拉树结构数据
const menuOptions = ref([]);
const getTreeSelect = () => {
  menuOptions.value = [];
  proxy.$api.menu.getMenuTreeSelect().then((res) => {
    const menu = { id: 0, label: "根菜单", children: [] };
    menu.children = res.data.menus;
    menuOptions.value.push(menu);
    console.log(
      "%c [ menuOptions.value ]-428",
      "font-size:13px; background:pink; color:#bf2c9f;",
      menuOptions.value
    );
  });
};
// 新增按钮
const handleAdd = () => {
  // 强制清除表单数据
  resetFormMenu();
  getTreeSelect();
  getAction.action = "add";

  dialogVisible.value = true;
};
// 编辑按钮
const handleEdit = (row) => {
  getTreeSelect();
  getAction.action = "edit";
  dialogVisible.value = true;
  nextTick(() => {
    Object.assign(formMenu, row);
    formMenu.enable = formMenu.enable.toString();
    formMenu.keepAlive = formMenu.keepAlive === true ? "1" : "0";
  });
};
// 表单取消时也需要重置表单内容
const handleCancel = () => {
  dialogVisible.value = false;
  proxy.$refs.formMenuRef.resetFields();
};
//彻底清除表单数据，防止数据莫名回显
const resetFormMenu = () => {
  Object.assign(formMenu, {
    id: "",
    parentId: "",
    menuType: "M",
    label: "",
    path: "",
    icon: "",
    url: "",
    enable: "",
    keepAlive: "",
  });
};
// 新增用户，提交表单内容
const onSubmit = () => {
  // 表单内容验证，表单的ref属性拿到表单，使用el-api校验
  proxy.$refs.formMenuRef.validate(async (valid) => {
    if (valid) {
      if (getAction.action === "add") {
        console.log("jinruadd");
        const currentUser = localStorage.getItem("username");
        console.log("fm", formMenu);
        let formMenudAdd = reactive({
          parentId: formMenu.parentId,
          menuType: formMenu.menuType,
          name: formMenu.path.match(/\/([^\/]+)$/)[1],
          label: formMenu.label,
          path: formMenu.path,
          icon: formMenu.icon,
          url: formMenu.url,
          menuSort: formMenu.menuSort,
          enable: formMenu.enable,
          keepAlive: formMenu.keepAlive === "" ? 0 : 1,
          createBy: currentUser,
        });
        // await只会返回给他最近的async回调函数！！！否则报错
        const res = await proxy.$api.menu.addMenu(formMenudAdd);
        // 如果成功，则清空form表单，并关闭弹框
        if (res) {
          //需要注意的是：使用validate、resetFields，需要在表单内容上加prop绑定表单相应属性才会生效
          proxy.$refs.formMenuRef.resetFields();
          // 关闭弹框
          dialogVisible.value = false;
          ElMessage({
            showClose: true,
            message: res.data,
            type: "success",
          });
          // 重新获取数据
          getMenuData(config);
        }
        // 编辑用户信息
      } else if (getAction.action === "edit") {
        let formMenudEdit = reactive({
          id: formMenu.id,
          parentId: formMenu.parentId,
          menuType: formMenu.menuType,
          name: formMenu.path.match(/\/([^\/]+)$/)[1],
          label: formMenu.label,
          path: formMenu.path,
          icon: formMenu.icon,
          url: formMenu.url,
          menuSort: formMenu.menuSort,
          enable: formMenu.enable,
          keepAlive: formMenu.keepAlive,
        });
        const res = await proxy.$api.menu.updateMenuData(formMenudEdit);
        if (res) {
          proxy.$refs.formMenuRef.resetFields();
          dialogVisible.value = false;
          ElMessage({
            showClose: true,
            message: res.data,
            type: "success",
          });
          // 重新获取数据
          getMenuData(config);
        }
      }
    } else {
      ElMessage.error("请填写完整信息");
    }
  });
};
// 删除菜单
const handleRemove = (row) => {
  ElMessageBox.confirm("确定要删除吗", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      let res = await proxy.$api.menu.deleteMenu({ id: row.id });
      if (res) {
        ElMessage({
          type: "success",
          message: res.data,
        });
        getMenuData(config);
      }
    })
    .catch(() => {
      // catch error
    });
};
let ids = reactive([]);
// 批量选中
const handleSelectionChange = (val) => {
  ids = [];
  val.forEach((item) => {
    ids.push(item.id);
  });
};
// 批量删除
const handleDelList = () => {
  ElMessageBox.confirm("确定要删除吗", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      if (ids.length !== 0) {
        let res = await proxy.$api.menu.batchDelMenu(ids);
        if (res) {
          ElMessage({
            showClose: true,
            message: res.data,
            type: "success",
          });
          getRoleData(config);
          ids = [];
        }
      } else {
        ElMessage({
          showClose: true,
          message: "请选择要删除的用户",
          type: "warning",
        });
      }
    })
    .catch((err) => {});
};

const iconSelectRef = ref();
const selectedSvgIcon = (name) => {
  console.log(
    "%c [ name ]-617",
    "font-size:13px; background:pink; color:#bf2c9f;",
    name
  );
  formMenu.icon = name;
};

// return {
//   menuTableLabel,
//   config,
//   formMenu,
//   rules,
//   getAction,
//   menuFormInline,
//   menuTableData,
//   dialogVisible,
//   menuOptions,
//   handleAdd,
//   handleEdit,
//   handleCancel,
//   onSubmit,
//   handleRemove,
//   handleDelList,
//   handleSelectionChange,
//   handleSearch,
//   changeMenuStatu,
// };
</script>

<style lang="less" scoped>
.table {
  position: relative;
  height: 520px;
  .pager {
    position: absolute;
    right: 0;
    bottom: -10px;
  }
}
.user-header {
  display: flex;
  justify-content: space-between;
  padding-bottom: -5px;
  padding-top: -10px;
}

// .el-select {
//   width: 196px;
//   margin-right: 20px;
// }
.el-input-number {
  width: 180px;
}
// 输入框宽度限制
.input_add {
  width: 196px;
  margin-right: 20px;
  &:hover {
    width: 196px;
  }
  &:focus {
    width: 196px;
  }
}
.end {
  justify-content: end;
  margin-bottom: 0px;
}
.icons {
  height: 18px;
  width: 18px;
}
.dialog-footer {
  display: flex;
  justify-content: end;
}
.treeSelect {
  width: 100% !important;
}
// 表格图标,i标签包裹。需要先设置i标签的大小，再deep到svg
.table-icon {
  width: 18px;
  height: 18px;
  :deep(svg) {
    width: 100%;
    height: 100%;
  }
}
</style>
